//
//  UserViewModel.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/1/11.
//

import Foundation
import LeanCloud
import SwiftUI

var userManager = UserManager()

class UserManager : BaseViewModel {
    private let userDefaults = UserDefaults.standard
    private let userKey = "userKey"
    @Published var isLoginSuc :Bool  = false //用于登录监听
    @Published var user : UserBean? {
        didSet {
            //保存本地数据
            saveUser()
        }
    }
    
    override init() {
        super.init()
        self.user = loadUser()
    }
    
    //保存本地数据
    private func saveUser() {
        if let user = user {
            let encoder = JSONEncoder()
            if let encodedData = try? encoder.encode(user) {
                userDefaults.set(encodedData, forKey: userKey)
            }
        } else {
            userDefaults.removeObject(forKey: userKey)
        }
    }
    //加载本地数据
    private func loadUser() -> UserBean? {
        if let encodedData = userDefaults.data(forKey: userKey),
           let decodedUser = try? JSONDecoder().decode(UserBean.self, from: encodedData) {
            return decodedUser
        }
        return nil
    }
    
    /**
     * 账号查询
     */
    func queryAccount() async throws -> UserBean? {
        let query = LCQuery(className: "User_")
        query.whereKey("objectId", .equalTo(userManager.getUserId()))
        return try await retry(maxRetries: 5, retryDelayMillis: 300) {
            return try await LeancloudManager.instance.getFirst(query: query, modeType: UserBean.self)
        }
    }
    
    func saveUser(_ user: UserBean?) {
        if user == nil {
            return
        }
        DispatchQueue.main.async {
            self.user = user
        }
    }
    
    //如果只更改里面的值，并不会刷新试图
    //由于UserManager是全局的，图个需要当前试图刷新，则需要在当前试图上加上
    //    @EnvironmentObject var userManager: UserManager //加这个才能刷新
    func update() {
        //所以重新赋值
        DispatchQueue.main.async {
            self.user = self.user
        }
    }
    
    func request(_ isLoading: Bool = false) {
        Task {
            DispatchQueue.main.async {
                if isLoading {
                    showLoadPopup()
                }
            }
            if let user = user {
                try await LeancloudManager.instance.save(todo: user)
            }
            DispatchQueue.main.async {
                hideLoadPopup()
            }
        }
    }
    
    //赠送云相册
    func requestReceiveCloud(capacityType: Int) {
        request {
            //查询配置
            let config = try await retry(maxRetries: 5, retryDelayMillis: 200) {
                let query = LCQuery(className: "CloudCapacityConfig")
                query.whereKey("type", .equalTo(capacityType))
                return try await LeancloudManager.instance.getFirst(query: query, modeType: CloudCapacityConfigBean.self)
            }
            try check(config != nil) {
                "查找不到容量信息"
            }
            let capacity = config?.capacity
            try check(capacity != nil) {
                "查找不到容量信息"
            }
            //保存云相册容量
            try await retry(maxRetries: 5, retryDelayMillis: 200) {
                capacity?.userId = self.getUserId()
                let day = Int64(capacity?.day ?? 1)
                capacity?.expirationTime = getMillisecond(Date().timeIntervalSince1970) + Int64(1000 * 60 * 60 * 24) * day
                try await LeancloudManager.instance.save(todo: capacity!)
            }
            return ""
        } suc: { _ in
            
        } fail: {_ in
        }
    }
    
    func requestAsync(user: UserBean?) async throws {
        if let user = user {
            try await retry(maxRetries: 10, retryDelayMillis: 100) {
                try await LeancloudManager.instance.save(todo: user)
            }
        }
    }
    
    func isLogin() -> Bool{
        return user != nil
    }
    
    func doLogin() {
        update()
        BackupsManager.shared.getDelegateConfig()?.clearRoleList()
        isLoginSuc = true
    }
    
    func doLogOut() {
        user = nil
        BackupsManager.shared.getDelegateConfig()?.clearRoleList()
        isLoginSuc = false
    }
    
    func getUser() -> UserBean? {
        return user
    }
    
    func getUserId() -> String {
        return user?.objectId ?? ""
    }
    
    func getName() -> String {
        return user?.name ?? ""
    }
    
    func getAvatar() -> String {
        return user?.headUrl ?? ""
    }
    
    func getSexStr() -> String {
        return user?.getSexStr() ?? "男"
    }
    
    private func getVipExpiration() ->Int64 {
        return user?.vipExpiration ?? 0
    }
    
    func isVip() -> Bool{
        if getVipExpiration() < 0 {
            return true
        }
        if getVipExpiration() > getMillisecond(Date().timeIntervalSince1970){
            return true
        }
        return false
    }
    
    func getVipExpirationStr() -> String {
        if getVipExpiration() < 0 {
            return "已解锁永久Pro"
        }
        if getVipExpiration() == 0 {
            return "解锁Pro可享有更高的权益"
        }
        if getVipExpiration() > getMillisecond(getCurTime()) {
            return "已解锁Pro,过期时间:\(TimeUtils.getDate(time: getVipExpiration(), format: "yyyy-MM-dd"))"
        }
        return "Pro已过期::\(TimeUtils.getDate(time: getVipExpiration(), format: "yyyy-MM-dd"))"
    }
    
    func getExtraConfig() -> UserExtraConfig {
        let extra = user?.getExtraConfig() ?? UserExtraConfig()
        user?.extraConfig = extra
        return extra
    }
    //无限用户
    func isInfinite()-> Bool {
        return user?.vipSource == VipSourceType.infinite.rawValue || user?.vipSource == VipSourceType.custom_infinite.rawValue
    }
    
    //定制用户
    func isCustom() -> Bool {
        return user?.vipSource == VipSourceType.custom.rawValue || user?.vipSource == VipSourceType.custom_infinite.rawValue
    }
    /**
     * 减少ai次数
     */
    func deductAiChatCount(_ count: Double = 1) {
        //如果是不限量，则不扣除
        if (!isNoLimitAi()) {
            doAiChatCount(-count)
        }
    }
    
    /**
     * 减少/增加ai次数
     */
    func doAiChatCount(_ count: Double = 1) {
        DispatchQueue.main.async {
            if !self.isLogin() {
                AppStorageManager.shared.localAiCount += count
                return
            }
            AppStorageManager.shared.deductAiCount += count
            self.update()
        }
    }
    
    func getAiCount() -> Double {
        if !isLogin() {
            return AppStorageManager.shared.localAiCount
        }
        if isInfinite() {
            return 999999.0
        }
        let aiChatCount = user?.aiChatCount ?? 0
        return aiChatCount + AppStorageManager.shared.deductAiCount
    }
    
    //是不是畅聊
    func isNoLimitAi()  -> Bool {
        if !isLogin() {
            return false
        }
        return user?.aiChatCountExpiration ?? 0 >= getMillisecond(getCurTime())
    }
    
    func getAiCountStr(isShowCount: Bool = true) -> String {
        if isInfinite() {
            return "无限"
        }
        if (isNoLimitAi() && !isShowCount) {
            let curTime = getMillisecond(getCurTime())
            return TimeUtils.getDiffDayStr2(
                time: user?.aiChatCountExpiration ?? curTime,
                time2: curTime)
        }
        return getAiCount().formatNumber()
    }
}
